#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ipcapi.h"

// url示例:
// 	"tcp://127.0.0.1:9901"
// 	"tcp://127.0.0.1:9902"
// 	"ipc:///tmp/reqrep"  /* 这种写法要求路径/tmp能够创建reqrep文件 */
// 	"ipc:///tmp/pubsub"
static char REQREP_SERVER[256] = {0};
static char PUBSUB_SERVER[256] = {0};

#if defined(WIN32) || defined(WIN64) || defined(WINCE) || defined(_MSC_VER)
/* ----- windows begin ----- */
#include <windows.h>
#include <process.h>
#define SLEEP(s) Sleep(s * 1000)
/* ----- windows end ----- */
#else
/* ----- linux begin ----- */
#include <unistd.h>
#define SLEEP(s) sleep(s)
/* ----- linux end ----- */
#endif

class MyReqRepServer : public CIpcApiServer
{
public:
    void OnRequest(
        char* reqBuff, int32_t reqBuffSize,
        char* rspBuff, int32_t& rspBuffSize)
	{
        printf("MyReqRepServer OnRequest: %s \r\n", reqBuff);
        rspBuffSize = rspBuffSize > reqBuffSize ? reqBuffSize : rspBuffSize;
        memcpy(rspBuff, reqBuff, rspBuffSize);
	}

    void OnErrorPrint(const char* message) {
        printf("MyReqRepServer OnError: %s \r\n", message);
    }
};

class MyPubSubServer : public CIpcApiServer
{
public:
    void OnErrorPrint(const char* message) {
        printf("MyPubSubServer OnError: %s \r\n", message);
    }
};

class MyReqRepClient: public CIpcApiClient
{
public:
    void OnErrorPrint(const char* message) {
        printf("MyReqRepClient OnError: %s \r\n", message);
    }
};

class MyPubSubClient: public CIpcApiClient
{
public:
    void OnMessage(char* msg, int32_t msgSize)
    {
        printf("MyPubSubClient OnMessage: %s \r\n", msg);
    }

    void OnError(const char* message) {
        printf("MyPubSubClient OnError: %s \r\n", message);
    }
};

int main()
{
	int32_t ret;
	char buff[128] = {0};
	int32_t buffSize = 128;

	fprintf(stdout, " ---------- Create url ---------- \r\n");

	IpcApiCreateUrl(IPCAPI_TYPE_REQREP, REQREP_SERVER, sizeof(REQREP_SERVER), "reqrep-test");
	IpcApiCreateUrl(IPCAPI_TYPE_PUBSUB, PUBSUB_SERVER, sizeof(PUBSUB_SERVER), "pubsub-test");

	printf("REQREP_SERVER: %s\r\n", REQREP_SERVER);
	printf("PUBSUB_SERVER: %s\r\n", PUBSUB_SERVER);

	fprintf(stdout, " ---------- Server init ---------- \r\n");

	MyReqRepServer reqrepServer1;
	MyPubSubServer pubsubServer2;

	ret = reqrepServer1.Init(REQREP_SERVER, IPCAPI_TYPE_REQREP);
	printf("reqrepServer1.Init: ret = %d \r\n", ret);

	ret = pubsubServer2.Init(PUBSUB_SERVER, IPCAPI_TYPE_PUBSUB);
	printf("pubsubServer2.Init: ret = %d \r\n", ret);

	SLEEP(1);

	fprintf(stdout, " ---------- Client init ---------- \r\n");

	MyReqRepClient reqrepClient1;
	MyPubSubClient pubsubClient2;
	MyPubSubClient pubsubClient3;

	ret = reqrepClient1.Init(REQREP_SERVER, IPCAPI_TYPE_REQREP);
	printf("reqrepClient1.Init: ret = %d \r\n", ret);

	ret = pubsubClient2.Init(PUBSUB_SERVER, IPCAPI_TYPE_PUBSUB);
	printf("pubsubClient2.Init: ret = %d \r\n", ret);

	ret = pubsubClient3.Init(PUBSUB_SERVER, IPCAPI_TYPE_PUBSUB);
	printf("pubsubClient3.Init: ret = %d \r\n", ret);

	ret = pubsubClient2.SetTopic("aabb");
	printf("pubsubClient2.SetTopic: ret = %d \r\n", ret);

	ret = pubsubClient3.SetTopic("ccdd");
	printf("pubsubClient3.SetTopic: ret = %d \r\n", ret);

	SLEEP(1);

	fprintf(stdout, " ---------- Test---------- \r\n");

	buffSize = sizeof(buff);
	ret = reqrepClient1.Request("1234", 4, buff, buffSize);
	printf("reqrepClient1.Request: ret/%d \"1234\" --> \"%s\" \r\n", ret, buff);

	SLEEP(1);

	buffSize = sizeof(buff);
	ret = reqrepClient1.Request("5678", 4, buff, buffSize);
	printf("reqrepClient1.Request: ret/%d \"5678\" --> \"%s\" \r\n", ret, buff);

	SLEEP(1);

	snprintf(buff, sizeof(buff), "aabb:1234");
	pubsubServer2.Broadcast(buff, strlen(buff));

	SLEEP(1);

	snprintf(buff, sizeof(buff), "ccdd:4567");
	pubsubServer2.Broadcast(buff, strlen(buff));

	SLEEP(1);

	fprintf(stdout, " ---------- Enter to exit ---------- \r\n");
	getchar();
	return 0;
}
